<template>
	<ul class="sp-contextmenu-top-ul">
		<li v-for="item in pobj.menulist" class="topmenu-li" :key="item.btnName">
			<div v-if="item.menulist && item.menulist.length > 0" class="topmenu-has-child">
				<div class="topmenu-btn-wrapper" :class="{'sp-contextmenu-disable': !!item.disabled}">
					<i v-if="!item.icoName" class="topmenu-nav-icon"></i>
					<svg-icon v-else :icon-class="item.icoName" class="topmenu-nav-icon"></svg-icon>
					<span class="topmenu-nav-name">{{item.btnName}}</span>
					<i :class="iconDirClass"></i>
				</div>
				<sp-contextmenu-tree v-if="!item.disabled" :menulist="item.menulist" :dir="subtreeDir" ></sp-contextmenu-tree>
			</div>
			<div v-else @click.stop="!item.disabled ? fnHandler(item) : ''"
				 class="topmenu-leaf-btn topmenu-btn-wrapper"
				 :class="{'sp-contextmenu-disable': !!item.disabled}">
				<i v-if="!item.icoName" class="topmenu-nav-icon"></i>
				<svg-icon v-else :icon-class="item.icoName" class="topmenu-nav-icon"></svg-icon>
				<span class="topmenu-nav-name">{{item.btnName}}</span>
			</div>
		</li>
	</ul>
</template>
<script>
	import Vue from "/vue/libs/vue.esm.browser.min.js";
	let comname = 'sp-contextmenu';
	let obj = {
		all: {},
		menu: null,
		ev: null,
		show: function (name, pobj) {
			var menu = obj.all[name];
			if (menu) {
				menu.pobj.showtimes++;
			} else {
				if (!pobj) throw new Error('动态创建菜单必须传递pobj数据');
				var $ = window.$;
				var div = $('<div />').appendTo('body').end();
				pobj.name = name;
				new Vue({
					render: h => {
						return h(comname,
							{
								props: {
									pobj
								}
							}
						);
					},
					mounted() {
						pobj.showtimes++;
					}
				}).$mount(div[0]);
			}
		}
	};
	
	window.SPContextmenu = obj;
	$(document).bind('contextmenu click', function (ev) {
		$.each(obj.all, function (k, v) {
			$(v.$el).hide();
		});
		if (obj.menu) {
			var targetClientRect = ev.target.getBoundingClientRect();
			var left = targetClientRect.x + ev.offsetX;
			var top = targetClientRect.y + ev.offsetY;
			$(obj.menu.$el).css({ position: 'fixed', left: left + 'px', top: top + 'px' }).show();
			// 确定子菜单定位方式，简单按4个象限处理
			var jWin = $(window);
			var winW = jWin.width();
			var winH = jWin.height();
			var dir = 2;
			if (ev.clientX <= winW / 2) {
				if (ev.clientY <= winH / 2) {
					dir = 2;
				} else {
					dir = 3;
				}
			} else {
				if (ev.clientY <= winH / 2) {
					dir = 1;
				} else {
					dir = 4;
				}
			}
			obj.menu.subtreeDir = dir;
			obj.menu = null;// 定位完成，设置为空
			obj.target = ev.target;// 全局对象中记录右键上下文菜单事件对象，后面的处理可能需要
			return false;
		};
	});
	
	httpVueLoaderWrap("/vue/components/contextmenu/tree.vue").then(m => {		
		module.exports = {
			name: comname,
			components: {
				"sp-contextmenu-tree": m
			},
			data() {
				return {
					subtreeDir: 1
				};
			},
			props: {
				pobj: {
					type: Object,
					required: true,
					default() {
						return {
							name: '',
							showtimes: 0,
							menulist: [
								{
									fnHandler: '',
									icoName: '',
									btnName: '',
									menulist: [],
									disabled: true
								}
							]
						};
					}
				}
			},
			computed: {
				iconDirClass() {
					return this.subtreeDir === 2 || this.subtreeDir === 3 ? 'sp-contextmenu-right-icon' : 'sp-contextmenu-left-icon';
				}
			},
			watch: {
				'pobj.showtimes'(v) {
					obj.menu = this;// 全局对象中记录当前要显示的菜单对象
					obj.menuName = this.pobj.name;// 记录最后打开的菜单名称
				}
			},
			methods: {
				fnHandler(item) {
					if (item.fnHandler && typeof item.fnHandler === 'function') {
						var arg = { menuItem: item, target: obj.target, menuName: obj.menuName };
						item.fnHandler(arg);
					}
				}
			},
			mounted() {
				
				if (!this.pobj.name) {
					this.$destroy();
				} else {
					if (!('showtimes' in this.pobj)) {
						throw new Error('pobj必须包含属性showtimes');
					}
					obj.all[this.pobj.name] = this;
					$(this.$el).on('contextmenu', function () { return false; }).hide();
				}
			},
			beforeDestroy() {
				this.$el.parentNode.removeChild(this.$el);
				if (this.pobj.name) {
					delete obj.all[this.pobj.name];
				}
			}
		};
	});
</script>
<style scoped src="/nodejs/importscssfile?file=vue/components/contextmenu/index_scope.scss"></style>